home *** CD-ROM | disk | FTP | other *** search
/ Amiga News 96 / Amiga News 96.iso / amig_ad_os / laurent_faillie / lfcinter / lfci_fnc.cxx < prev    next >
C/C++ Source or Header  |  1977-12-31  |  28KB  |  701 lines

  1. /***************************************************************************\
  2. *  LFCI_fnc.cxx                                                             *
  3. *  Projet : LFCInter                                                        *
  4. *      © LFSoft 1995-96                                                     *
  5. *                                                                           *
  6. *  Execution des fonctions internes et construction des arguments.          *
  7. *                                                                           *
  8. *   Note: Dans ce fichier il y a des caratères '(',')','{','}'... mis en    *
  9. *   commentaire. C'est uniquement pour permettre à mon éditeur de tester    *
  10. *   les blocs...                                                            *
  11. *                                                                           *
  12. \*************** Voir LFCInter pour plus d'informations ********************/
  13.  
  14. #include "LFCInter.h"
  15. #include "Token.h"
  16. #include "LFDStack.h"
  17. #include "LFCI_Cal.h"
  18. #include <stdio.h>
  19. #include <time.h>
  20. #include <string.h>
  21.  
  22. static void litargs(_token &ptr, _tablesmb *table_locale, LFDynaStack<_rep> &args, int nbreargs, const char *fonc){
  23. /* Lit un nombre fixe d'arguments.
  24.  *  -> ptr : pointe sur le premier argument,
  25.  *  -> args : Pile qui contiendra les arguments lus,
  26.  *  -> nbreargs : Nombre d'arguments à lire,
  27.  *  -> fonc : Nom de la fonction dont on lit les arguments...
  28.  */
  29.     if(*ptr != /*(*/ ')') FOREVER { // Lecture des arguments
  30.         args.Push( eval(ptr,table_locale,true) );
  31.         if(*ptr == ',')
  32.             ptr++;
  33.         else if(*ptr == /*(*/ ')') // C'était le dernier argument
  34.             break;
  35.         else {
  36.             cerr << "*E* Ligne " << calcligne(ptr) << ": Erreur de syntaxe pour " << fonc << ADEB( " (litargs:1)" << ) " !\n";
  37.             exit(5);
  38.         }
  39.     }
  40.  
  41.     if( nbreargs > args.length()+1 ){
  42.         cerr << "*E* Ligne " << calcligne(ptr) << ": Pas assez d'arguments ont été fournis pour " << fonc << ADEB( " (litargs:2)" << ) " !\n";
  43.         exit(5);
  44.     } else if( nbreargs < args.length()+1 )
  45.         cerr << "*A* Ligne " << calcligne(ptr) << ": Trop d'arguments ont été fournis pour " << fonc << ADEB( " (litargs:3)" << ) " !\n";
  46. }
  47.  
  48. _rep interne(_token &ptr,_tablesmb *table_locale){
  49. /* Execute une fonction émulée en interne...
  50.  *  <- ptr : pointe sur le nom de la fonction à émuler
  51.  *     table_locale : table locale au moment du passage des arguments
  52.  *  -> ptr : apres le #(# ')' de fermeture des arguments
  53.  */
  54.     LFDynaStack<_rep> args;
  55.     int idfonc = *ptr++;
  56.     _rep ret;
  57.  
  58.     if(*ptr++ != '(' /*)*/){
  59.         cerr << "*E* Ligne " << calcligne(ptr) << ":Erreur de syntaxe, un '(' était attendu\n" /*)*/
  60.                 "*E*  ... ou tentative pour obtenir l'adresse d'une fonction interne !\n";
  61.         exit(5);
  62.     }
  63.  
  64.     switch(idfonc){
  65.     case smbl_printf:{
  66.             _rep fmt; //Format de la chaîne à afficher
  67.             fmt=conv('*',eval(ptr, table_locale,true),ptr);
  68.             while(*ptr == ','){ // Lecture des autres arguments
  69.                 ptr++;
  70.                 _rep t=eval(ptr, table_locale,true);
  71.                 args.Push(t);
  72.             }
  73.  
  74.             const char *x = (const char *)fmt.val.ptr;
  75.             int na=0; // Numéro de l'argument lu
  76.  
  77.             while(*x){
  78.                 switch(*x){
  79.                 case '%':{
  80.                         string format;
  81.                         format='%';
  82.  
  83.                         switch(*++x){
  84.                         case '-':
  85.                         case '+':
  86.                         case ' ':
  87.                         case '#':
  88.                         case '0':
  89.                             format += *x++;
  90.                         }
  91.  
  92.                         if(*x=='*'){
  93.                             int i=conv('I',args[na++],ptr).val.entier;
  94.                             char t[10];
  95.                             sprintf(t,"%d",i);
  96.                             format += t;
  97.                             x++;
  98.                         } else while(isdigit(*x))
  99.                             format += *x++;
  100.  
  101.                         if(*x=='.'){
  102.                             format += *x++;
  103.                             if(*x=='*'){
  104.                                 int i=conv('I',args[na++],ptr).val.entier;
  105.                                 char t[10];
  106.                                 sprintf(t,"%d",i);
  107.                                 format += t;
  108.                                 x++;
  109.                             } else while(isdigit(*x))
  110.                                 format += *x++;
  111.                         }
  112.  
  113.                         if(*x=='h' || *x=='l' || *x=='L') // Modificateur (sans intérêt car il n'y a pas de short et de long)
  114.                             x++;
  115.  
  116.                         format += *x;
  117.  
  118.                         switch(*x){
  119.                         case 'c':
  120.                             ret=printf(format.c_str(),conv('C',args[na++],ptr).val.caractere);
  121.                             break;
  122.                         case 'd':
  123.                         case 'i':
  124.                         case 'o':
  125.                         case 'u':
  126.                         case 'x':
  127.                         case 'X':
  128.                             ret=printf(format.c_str(),conv('I',args[na++],ptr).val.entier);
  129.                             break;
  130.                         case 'n':
  131.                         case 'p':
  132.                         case 's':
  133.                             ret=printf(format.c_str(),conv('*',args[na++],ptr).val.ptr);
  134.                             break;
  135.                         case 'e':
  136.                         case 'E':
  137.                         case 'f':
  138.                         case 'G':
  139.                         case 'g':
  140.                         default:
  141.                             putchar(*x);
  142.                         }
  143.                     }
  144.                     break;
  145.                 default:
  146.                     putchar(*x);
  147.                 }
  148.                 x++;
  149.             }
  150.         }
  151.         break;
  152.     case smbl_sprintf:{
  153.             char *chaine; // Chaîne à affecter
  154.             _rep fmt; //Format de la chaîne à afficher
  155.  
  156.             chaine = (char *)conv('*',eval(ptr, table_locale,true),ptr).val.ptr; // Lecture du pointeur sur la chaîne
  157.             if(*ptr != ','){
  158.                 cerr << "*E* Ligne " << calcligne(ptr) << " Fonction sprintf(): Il manque des arguments.\n";
  159.                 exit(5);
  160.             }
  161.             ptr++;
  162.  
  163.             fmt=conv('*',eval(ptr, table_locale,true),ptr);
  164.  
  165.             while(*ptr == ','){ // Lecture des autres arguments
  166.                 ptr++;
  167.                 _rep t=eval(ptr, table_locale,true);
  168.                 args.Push(t);
  169.             }
  170.  
  171.             string res;
  172.  
  173.             const char *x = (const char *)fmt.val.ptr;
  174.             int na=0; // Numéro de l'argument lu
  175.  
  176.             while(*x){
  177.                 switch(*x){
  178.                 case '%':{
  179.                         string format("%");
  180.                         int lmt=0; // Si !=0 si une longueur mini a été demandée
  181.     // /!\ si les flotants sont utilisables, il faut aussi tenir compte des '%.?'
  182.  
  183.                         switch(*++x){
  184.                         case '-':
  185.                         case '+':
  186.                         case ' ':
  187.                         case '#':
  188.                         case '0':
  189.                             format += *x++;
  190.                         }
  191.  
  192.                         if(*x=='*'){
  193.                             lmt=conv('I',args[na++],ptr).val.entier;
  194.                             char t[10];
  195.                             sprintf(t,"%d",lmt);
  196.                             format += t;
  197.                             x++;
  198.                         } else while(isdigit(*x)){
  199.                             lmt = lmt*10 + *x-'0';
  200.                             format += *x++;
  201.                         }
  202.  
  203.                         if(*x=='.'){
  204.                             format += *x++;
  205.                             if(*x=='*'){
  206.                                 int i=conv('I',args[na++],ptr).val.entier;
  207.                                 char t[10];
  208.                                 sprintf(t,"%d",i);
  209.                                 format += t;
  210.                                 x++;
  211.                             } else while(isdigit(*x))
  212.                                 format += *x++;
  213.                         }
  214.  
  215.                         if(*x=='h' || *x=='l' || *x=='L') // Modificateur (sans intérêt car il n'y a pas de short et de long)
  216.                             x++;
  217.  
  218.                         format += *x;
  219.  
  220.                         char *tmp=0;
  221.  
  222.                         switch(*x){
  223.                         case 'c':
  224.                             if(lmt)
  225.                                 tmp = new char[lmt+ 5];
  226.                             else
  227.                                 tmp = new char[5];
  228.  
  229.                             if(!tmp){
  230.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  231.                                 exit(5);
  232.                             }
  233.  
  234.                             sprintf(tmp,format.c_str(),conv('C',args[na++],ptr).val.caractere);
  235.                             break;
  236.  
  237.                         case 'd':
  238.                         case 'i':
  239.                         case 'u':
  240.                             {
  241.                                 int l=sizeof(int)/2*5; // Longueur théorique
  242.                                 if(lmt<l)
  243.                                     lmt=l;
  244.                             }
  245.                             tmp = new char[lmt+5];
  246.  
  247.                             if(!tmp){
  248.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  249.                                 exit(5);
  250.                             }
  251.  
  252.                             goto suite_sprintf_int;
  253.  
  254.                         case 'o':
  255.                             {
  256.                                 int l=sizeof(int)*3; // Longueur théorique
  257.                                 if(lmt<l)
  258.                                     lmt=l;
  259.                             }
  260.                             tmp = new char[lmt+5];
  261.  
  262.                             if(!tmp){
  263.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  264.                                 exit(5);
  265.                             }
  266.  
  267.                             goto suite_sprintf_int;
  268.  
  269.                         case 'x':
  270.                         case 'X':
  271.                             {
  272.                                 int l=sizeof(int)*2; // Longueur théorique
  273.                                 if(lmt<l)
  274.                                     lmt=l;
  275.                             }
  276.                             tmp = new char[lmt+5];
  277.  
  278.                             if(!tmp){
  279.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  280.                                 exit(5);
  281.                             }
  282.  
  283.             suite_sprintf_int:
  284.                             sprintf(tmp,format.c_str(),conv('I',args[na++],ptr).val.entier);
  285.                             break;
  286.  
  287.                         case 'n':
  288.     /*
  289.      *  Contrairement aux autres spécificateurs de conversion, le %n n'est pas
  290.      * utilisé pour afficher une valeur, mais affecte un entier, dont l'adresse
  291.      * est passée en paramêtre avec le nombre de caractères déja stockés.
  292.      */
  293.                             if(args[na].type() != 'R'){
  294.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Utilisation incorrecte du spécificateur '%n',\n"
  295.                                      << "*E* Ligne " << calcligne(ptr) << "l'argument " << na << " de sprintf() n'est ni une variable, ni une reference.\n";
  296.                                 exit(5);
  297.                             } else
  298.                                 RefAffecte(args[na++],(long)res.length(),ptr);
  299.                             break;
  300.  
  301.                         case 'p':
  302.                             {
  303.                                 int l=sizeof(void *)*2; // Longueur théorique
  304.                                 if(lmt<l)
  305.                                     lmt=l;
  306.                             }
  307.                             tmp = new char[lmt+5];
  308.  
  309.                             if(!tmp){
  310.                                 cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  311.                                 exit(5);
  312.                             }
  313.  
  314.                             sprintf(tmp,format.c_str(),conv('*',args[na++],ptr).val.ptr);
  315.                             break;
  316.                         case 's':
  317.                             {
  318.                                 const char *t = (char *)conv('*',args[na++],ptr).val.ptr;
  319.                                 int l=strlen(t); // Longueur théorique
  320.                                 if(lmt<l)
  321.                                     lmt=l;
  322.  
  323.                                 tmp = new char[lmt+5];
  324.  
  325.                                 if(!tmp){
  326.                                     cerr << "*E* Ligne " << calcligne(ptr) << ": Manque de mémoire.\n";
  327.                                     exit(5);
  328.                                 }
  329.                                 sprintf(tmp,format.c_str(),t);
  330.                             }
  331.                             break;
  332.                         case 'e':
  333.                         case 'E':
  334.                         case 'f':
  335.                         case 'G':
  336.                         case 'g':
  337.                         default:
  338.                             res += *x;
  339.                         }
  340.                         if(tmp){
  341.                             res += tmp;
  342.                             delete[] tmp;
  343.                             tmp = 0;
  344.                         }
  345.                     }
  346.                     break;
  347.                 default:
  348.                     res += *x;
  349.                 }
  350.                 x++;
  351.             }
  352.             strcpy(chaine, res.c_str());
  353.         }
  354.         break;
  355.     case smbl_putchar:
  356.         litargs(ptr, table_locale,  args, 1, "putchar");
  357.         ret=conv('I',args[0],ptr);
  358.         ret=putchar(ret.val.entier);
  359.         break;
  360.     case smbl_puts:
  361.         litargs(ptr, table_locale,  args, 1, "puts");
  362.         ret=puts((char *)conv('*',args[0],ptr).val.ptr);
  363.         break;
  364.     case smbl_gets:
  365.         litargs(ptr, table_locale,  args, 1, "gets");
  366.         ret=gets((char *)conv('*',args[0],ptr).val.ptr);
  367.         break;
  368.     case smbl_getchar:
  369.         litargs(ptr, table_locale,  args, 0, "getchar");
  370.         ret=getchar();
  371.         break;
  372.     case smbl_flushstdout:
  373.     // Cette fonction n'est pas standard mais pallie au manque de "fichier" dans
  374.     // la version 1.0 de l'interpréteur...
  375.         litargs(ptr, table_locale,  args, 0, "flushstdout");
  376.         fflush(stdout);
  377.         break;
  378.     case smbl_atoi:
  379.         litargs(ptr, table_locale,  args, 1, "atoi");
  380.         ret = atoi((char *)conv('*',args[0],ptr).val.ptr);
  381.         break;
  382.     case smbl_strcat:
  383.         litargs(ptr, table_locale,  args, 2, "strcat");
  384.         ret = _rep( (void *)strcat( (char *)conv('*',args[0],ptr).val.ptr,
  385.                       (char *)conv('*',args[1],ptr).val.ptr ),
  386.                     '*',string("C") );
  387.         break;
  388.     case smbl_strchr:
  389.         litargs(ptr, table_locale,  args, 2, "strchr");
  390.         ret = _rep( (void *)strchr( (char *)conv('*',args[0],ptr).val.ptr,
  391.                                             conv('I',args[1],ptr).val.entier ),
  392.                     '*',string("C") );
  393.         break;
  394.      case smbl_strcmp:
  395.          litargs(ptr, table_locale,  args, 2, "strcmp");
  396.          ret = strcmp( (char *)conv('*',args[0],ptr).val.ptr,
  397.                        (char *)conv('*',args[1],ptr).val.ptr );
  398.          break;
  399.     case smbl_strcpy:
  400.         litargs(ptr, table_locale,  args, 2, "strcpy");
  401.         ret = _rep( (void *)strcpy( (char *)conv('*',args[0],ptr).val.ptr,
  402.                                     (char *)conv('*',args[1],ptr).val.ptr ),
  403.                     '*',string("C") );
  404.         break;
  405.     case smbl_strerror:
  406.         litargs(ptr, table_locale,  args, 1, "strerror");
  407.         ret = _rep( (void *)strerror(conv('I',args[0],ptr).val.entier),
  408.                     '*',string("C") );
  409.         break;
  410.     case smbl_strlen:
  411.         litargs(ptr, table_locale,  args, 1, "strlen");
  412.         ret=(int)strlen((char *)conv('*',args[0],ptr).val.ptr);
  413.         break;
  414.     case smbl_strncat:
  415.         litargs(ptr, table_locale,  args, 3, "strncat");
  416.         ret = _rep( (void *)strncat( (char *)conv('*',args[0],ptr).val.ptr,
  417.                       (char *)conv('*',args[1],ptr).val.ptr,
  418.                       conv('I',args[2],ptr).val.entier ),
  419.                     '*',string("C") );
  420.         break;
  421.     case smbl_strncmp:
  422.         litargs(ptr, table_locale,  args, 3, "strncmp");
  423.         ret = strncmp( (char *)conv('*',args[0],ptr).val.ptr,
  424.                       (char *)conv('*',args[1],ptr).val.ptr,
  425.                       conv('I',args[2],ptr).val.entier );
  426.         break;
  427.     case smbl_strncpy:
  428.         litargs(ptr, table_locale,  args, 3, "strncpy");
  429.         ret = _rep( (void *)strncpy( (char *)conv('*',args[0],ptr).val.ptr,
  430.                                     (char *)conv('*',args[1],ptr).val.ptr,
  431.                                     conv('I',args[2],ptr).val.entier ),
  432.                     '*',string("C") );
  433.         break;
  434.     case smbl_strrchr:
  435.         litargs(ptr, table_locale,  args, 2, "strrchr");
  436.         ret = _rep( (void *)strrchr( (char *)conv('*',args[0],ptr).val.ptr,
  437.                                             conv('I',args[1],ptr).val.entier ),
  438.                     '*',string("C") );
  439.         break;
  440.     case smbl_strdup:
  441.         litargs(ptr, table_locale,  args, 1, "strdup");
  442.         ret=_rep( (void *)strdup((char *)conv('*',args[0],ptr).val.ptr),
  443.                     '*',string("C") );
  444.         break;
  445.     case smbl_stricmp:
  446.     case smbl_strcasecmp:
  447.          litargs(ptr, table_locale,  args, 2, "strcasecmp");
  448.          ret = strcasecmp( (char *)conv('*',args[0],ptr).val.ptr,
  449.                        (char *)conv('*',args[1],ptr).val.ptr );
  450.          break;
  451.     case smbl_strnicmp:
  452.     case smbl_strncasecmp:
  453.         litargs(ptr, table_locale,  args, 3, "strncasecmp");
  454.         ret = strncasecmp( (char *)conv('*',args[0],ptr).val.ptr,
  455.                       (char *)conv('*',args[1],ptr).val.ptr,
  456.                       conv('I',args[2],ptr).val.entier );
  457.         break;
  458.     case smbl_strpbrk:
  459.         litargs(ptr, table_locale,  args, 2, "strpbrk");
  460.         ret = _rep( (void *)strpbrk( (char *)conv('*',args[0],ptr).val.ptr,
  461.                                      (char *)conv('*',args[1],ptr).val.ptr),
  462.                     '*',string("C") );
  463.         break;
  464.     case smbl_strstr:
  465.         litargs(ptr, table_locale,  args, 2, "strstr");
  466.         ret = _rep( (void *)strstr( (char *)conv('*',args[0],ptr).val.ptr,
  467.                                      (char *)conv('*',args[1],ptr).val.ptr),
  468.                     '*',string("C") );
  469.         break;
  470.     case smbl_strcoll:
  471.          litargs(ptr, table_locale,  args, 2, "strcoll");
  472.          ret = strcoll( (char *)conv('*',args[0],ptr).val.ptr,
  473.                        (char *)conv('*',args[1],ptr).val.ptr );
  474.          break;
  475.     case smbl_strcspn:
  476.          litargs(ptr, table_locale,  args, 2, "strcspn");
  477.          ret = (int)strcspn( (char *)conv('*',args[0],ptr).val.ptr,
  478.                         (char *)conv('*',args[1],ptr).val.ptr );
  479.          break;
  480.     case smbl_strspn:
  481.          litargs(ptr, table_locale,  args, 2, "strspn");
  482.          ret = (int)strspn( (char *)conv('*',args[0],ptr).val.ptr,
  483.                        (char *)conv('*',args[1],ptr).val.ptr );
  484.          break;
  485.     case smbl_strtok:
  486.         litargs(ptr, table_locale,  args, 2, "strtok");
  487.         ret = _rep( (void *)strtok( (char *)conv('*',args[0],ptr).val.ptr,
  488.                                     (char *)conv('*',args[1],ptr).val.ptr),
  489.                     '*',string("C") );
  490.         break;
  491.     case smbl_strtol:
  492.         litargs(ptr, table_locale,  args, 3, "strtol");
  493.         ret = (long)strtol( (char *)conv('*',args[0],ptr).val.ptr,
  494.                             (char **)conv('*',args[1],ptr).val.ptr,
  495.                             conv('I',args[2],ptr).val.entier );
  496.         break;
  497.     case smbl_swab:
  498.         litargs(ptr, table_locale,  args, 3, "swab");
  499. #ifdef AMIGA
  500. /* buggue des includes de GCC ? Pour le borland & pour le compilateur natif du
  501.  * VAX cette fonction devrait prendre des 'char *' comme arguments...
  502.  */
  503.         swab( (const void *)conv('*',args[0],ptr).val.ptr,
  504.               (void *)conv('*',args[1],ptr).val.ptr,
  505.               conv('I',args[2],ptr).val.entier);
  506. #else
  507.         swab( (char *)conv('*',args[0],ptr).val.ptr,
  508.               (char *)conv('*',args[1],ptr).val.ptr,
  509.               conv('I',args[2],ptr).val.entier);
  510. #endif
  511.         break;
  512.     case smbl_memchr:
  513.         litargs(ptr, table_locale,  args, 3, "memchr");
  514.         ret = _rep( (void *)memchr( (void *)conv('*',args[0],ptr).val.ptr,
  515.                                             conv('I',args[1],ptr).val.entier,
  516.                                             conv('I',args[2],ptr).val.entier ),
  517.                     '*',string("V") );
  518.         break;
  519.      case smbl_memcmp:
  520.          litargs(ptr, table_locale,  args, 3, "memcmp");
  521.          ret = memcmp( (void *)conv('*',args[0],ptr).val.ptr,
  522.                        (void *)conv('*',args[1],ptr).val.ptr,
  523.                         conv('I',args[2],ptr).val.entier );
  524.          break;
  525.     case smbl_memcpy:
  526.         litargs(ptr, table_locale,  args, 3, "memcpy");
  527.         ret = _rep( (void *)memcpy( (void *)conv('*',args[0],ptr).val.ptr,
  528.                                     (void *)conv('*',args[1],ptr).val.ptr,
  529.                                     conv('I',args[2],ptr).val.entier ),
  530.                     '*',string("V") );
  531.         break;
  532.     case smbl_memmove:
  533.         litargs(ptr, table_locale,  args, 3, "memmove");
  534.         ret = _rep( (void *)memmove( (void *)conv('*',args[0],ptr).val.ptr,
  535.                                     (void *)conv('*',args[1],ptr).val.ptr,
  536.                                     conv('I',args[2],ptr).val.entier ),
  537.                     '*',string("V") );
  538.         break;
  539.     case smbl_memset:
  540.         litargs(ptr, table_locale,  args, 3, "memset");
  541.         ret = _rep( (void *)memset( (void *)conv('*',args[0],ptr).val.ptr,
  542.                                     conv('I',args[1],ptr).val.entier,
  543.                                     conv('I',args[2],ptr).val.entier ),
  544.                     '*',string("V") );
  545.         break;
  546.     case smbl_memccpy:
  547.         litargs(ptr, table_locale,  args, 4, "memccpy");
  548.         ret = _rep( (void *)memccpy( (void *)conv('*',args[0],ptr).val.ptr,
  549.                                     (void *)conv('*',args[1],ptr).val.ptr,
  550.                                     conv('I',args[2],ptr).val.entier,
  551.                                     conv('I',args[3],ptr).val.entier ),
  552.                     '*',string("V") );
  553.         break;
  554.     case smbl_system:
  555.         litargs(ptr, table_locale,  args, 1, "system");
  556.         ret = system((char *)conv('*',args[0],ptr).val.ptr);
  557.         break;
  558.     case smbl_isdigit:
  559.         litargs(ptr, table_locale,  args, 1, "isdigit");
  560.         ret = isdigit(conv('I',args[0],ptr).val.entier);
  561.         break;
  562.     case smbl_islower:
  563.         litargs(ptr, table_locale,  args, 1, "islower");
  564.         ret = islower(conv('I',args[0],ptr).val.entier);
  565.         break;
  566.     case smbl_isspace:
  567.         litargs(ptr, table_locale,  args, 1, "isspace");
  568.         ret = isspace(conv('I',args[0],ptr).val.entier);
  569.         break;
  570.     case smbl_ispunct:
  571.         litargs(ptr, table_locale,  args, 1, "ispunct");
  572.         ret = ispunct(conv('I',args[0],ptr).val.entier);
  573.         break;
  574.     case smbl_isupper:
  575.         litargs(ptr, table_locale,  args, 1, "isupper");
  576.         ret = isupper(conv('I',args[0],ptr).val.entier);
  577.         break;
  578.     case smbl_isalpha:
  579.         litargs(ptr, table_locale,  args, 1, "isalpha");
  580.         ret = isalpha(conv('I',args[0],ptr).val.entier);
  581.         break;
  582.     case smbl_isxdigit:
  583.         litargs(ptr, table_locale,  args, 1, "isxdigit");
  584.         ret = isxdigit(conv('I',args[0],ptr).val.entier);
  585.         break;
  586.     case smbl_isalnum:
  587.         litargs(ptr, table_locale,  args, 1, "isalnum");
  588.         ret = isalnum(conv('I',args[0],ptr).val.entier);
  589.         break;
  590.     case smbl_isprint:
  591.         litargs(ptr, table_locale,  args, 1, "isprint");
  592.         ret = isprint(conv('I',args[0],ptr).val.entier);
  593.         break;
  594.     case smbl_isgraph:
  595.         litargs(ptr, table_locale,  args, 1, "isgraph");
  596.         ret = isgraph(conv('I',args[0],ptr).val.entier);
  597.         break;
  598.     case smbl_iscntrl:
  599.         litargs(ptr, table_locale,  args, 1, "iscntrl");
  600.         ret = iscntrl(conv('I',args[0],ptr).val.entier);
  601.         break;
  602.     case smbl_isascii:
  603.         litargs(ptr, table_locale,  args, 1, "isascii");
  604.         ret = isascii(conv('I',args[0],ptr).val.entier);
  605.         break;
  606. #ifdef AMIGA
  607.     case smbl_isiso:
  608. /* Cette fonction (ou macro) n'est pas définie sur tous les systèmes, même en
  609.  * utilisant GCC (par exemple, elle n'existe pas sur le MicroVAX).
  610.  */
  611.         litargs(ptr, table_locale,  args, 1, "isiso");
  612.         ret = isiso(conv('I',args[0],ptr).val.entier);
  613.         break;
  614. #endif
  615.     case smbl_toupper:
  616.         litargs(ptr, table_locale,  args, 1, "toupper");
  617.         ret = toupper(conv('I',args[0],ptr).val.entier);
  618.         break;
  619.     case smbl_tolower:
  620.         litargs(ptr, table_locale,  args, 1, "tolower");
  621.         ret = tolower(conv('I',args[0],ptr).val.entier);
  622.         break;
  623.     case smbl_toiso:
  624.         litargs(ptr, table_locale,  args, 1, "toiso");
  625.         ret = tolower(conv('I',args[0],ptr).val.entier);
  626.         break;
  627.     case smbl_time: // Attention: il FAUT un pointeur sur un long int sur beaucoup de systèmes
  628.         litargs(ptr, table_locale,  args, 1, "time");
  629.         ret = time( (time_t *)conv('*',args[0],ptr).val.ptr);
  630.         break;
  631.     case smbl_ctime:
  632.         litargs(ptr, table_locale,  args, 1, "ctime");
  633.         ret = _rep( (void *)ctime( (time_t *)conv('*',args[0],ptr).val.ptr),
  634.                     '*',string("C") );
  635.         break;
  636.     case smbl_clock:
  637.         litargs(ptr, table_locale,  args, 0, "clock");
  638.         ret=(long int)clock();
  639.         break;
  640. #ifndef __BCPLUSPLUS__
  641.     case smbl_sleep:
  642. /* sleep() n'est pas défini que sous un seul environnement: windows
  643.  *  le problème est que même lorsqu'on compile un programme ms-dos, le
  644.  *  borland ne défini pas cette fonction!
  645.  */
  646.         litargs(ptr, table_locale,  args, 1, "sleep");
  647.         ret = (int)sleep(conv('I',args[0],ptr).val.entier);
  648.         break;
  649. #endif
  650.     case smbl_realloc:
  651.         litargs(ptr, table_locale,  args, 2, "realloc");
  652.         ret=realloc((void *)conv('*',args[0],ptr).val.ptr,
  653.                     conv('L',args[1],ptr).val.literal);
  654.         break;
  655.     case smbl_malloc:
  656.         litargs(ptr, table_locale,  args, 1, "malloc");
  657.         ret=malloc(conv('L',args[0],ptr).val.literal);
  658.         break;
  659.     case smbl_free:
  660.         litargs(ptr, table_locale,  args, 1, "free");
  661.         free(conv('*',args[0],ptr).val.ptr); // Pas d'affectation car c'est une fonction void
  662.         break;
  663.     default:
  664.         cerr << "*F* Ligne " << calcligne(ptr) << ": Tentative d'exécuter une fonction interne non reconnue.\n"
  665.             "*F* Peut-être n'existe-elle pas sur ce système.";
  666.         exit(5);
  667.     }
  668.  
  669.     if( *ptr != /*(*/')' ){
  670.         cerr << "*E* Ligne " << calcligne(ptr) << ": Erreur de syntaxe pour " << ptr.obj() << ADEB( " (interne:1)" << ) " !\n";
  671.         exit(5);
  672.     }
  673.     ptr++; // On saute le /*(*/ ')'
  674.     return ret;
  675. }
  676.  
  677. _rep lancefonc(_token &ptr, _var_fonc *fonc, _tablesmb *table_locale){
  678. /* Lance l'exécution d'une fonction.
  679.  *  <- ptr : debut des arguments (après le '(' #)# )
  680.  *     fonc : Fonction à exécuter (DOIT être valide car aucun test n'est fait)
  681.  *     table_locale : table locale au moment du passage des arguments
  682.  *  -> ptr pointe sur ce qui suit les paramêtres (#(# après le ')' fermant )
  683.  */
  684.     LFDynaStack<_rep> args;
  685.  
  686.     if(*ptr != /*(*/ ')') FOREVER { // Lecture des arguments
  687.         args.Push( eval(ptr,table_locale,true) );
  688.         if(*ptr == ',')
  689.             ptr++;
  690.         else if(*ptr == /*(*/ ')') // C'était le dernier argument
  691.             break;
  692.         else {
  693.             cerr << "*E* Ligne " << calcligne(ptr) << ": Erreur de syntaxe pour " << ptr.obj() << ADEB( " (lancefonc:1)" << ) " !\n";
  694.             exit(5);
  695.         }
  696.     }
  697.  
  698.     ptr++; // On saute le /*(*/ ')'
  699.     return execfonc(fonc,args);
  700. }
  701.